﻿<%@ WebHandler Language="C#" Class="Apollo.Website.SAPExportAccounting" %>

using System;
using System.Web;
using System.Collections.Generic;
using System.Linq;
using Apollo.Modules.Salary;

namespace Apollo.Website
{

    public class SAPExportAccounting : IHttpHandler, System.Web.SessionState.IRequiresSessionState
    {
        public static string ACCOUNT_PF_SUFIX = "20000";
        public static string ACCOUNT_PJ_SUFIX = "30000";
        
        
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/csv";
            
            int accountingMonthId = 0;
            if (int.TryParse(context.Request["AccountingMonthId"], out accountingMonthId))
            { 
                // generate headers
                context.Response.Write(SAPExportMapping.GetCSVHeader());
                
                
                AccountingMonth month = Apollo.Application.CurrentSession
                    .QueryOver<AccountingMonth>()
                    .Where(a => a.Id == accountingMonthId)
                    .SingleOrDefault();
                
                if(month == null)
                    return;

                // add headers with the filename
                context.Response.AddHeader("Content-Disposition", "attachment;filename=\"SAP Export "+month.Name + " - " + DateTime.Now.ToString("ddMMyyyy") +".csv\"");
                
                string lastDayOfMonth = month.LastDay.ToString("ddMMyyyy");
                
                // payroll mappings
                IList<SAPExportMapping> mappings = Apollo.Application.CurrentSession
                    .QueryOver<SAPExportMapping>()
                    .Where(e => e.BelongsTo == null && e.State == State.Active && e.Type != SAPMappingType.Transaction)
                    .List();

                foreach (SAPExportMapping map in mappings) {
                    map.LastDayOfMonth = lastDayOfMonth;
                    map.AccountSufixPF = ACCOUNT_PF_SUFIX;
                    map.AccountSufixPJ = ACCOUNT_PJ_SUFIX;
                }
                
                // generate line foreach commission payroll
                foreach (Payroll payroll in Apollo.Application.CurrentSession
                                            .QueryOver<Payroll>()
                                            .Where(p => p.AccountingMonth.Id == accountingMonthId)
                                            .List()) {
                    
                    // load all payroll components
                    IList<PayrollComponent> components = Apollo.Application.CurrentSession
                                            .QueryOver<PayrollComponent>()
                                            .Where(c => c.Payroll.Id == payroll.Id)
                                            .List();
                    
                    // generate line for each mapping
                    foreach (SAPExportMapping map in mappings) {
                        
                        // generate lines
                        switch (map.Type) {
                            case SAPMappingType.BaseIncome:
                                context.Response.Write(map.GetCSVRow(payroll.BaseIncomeValue
                                    , payroll.Employee.InternalCode, payroll.Employee.EmployeeType
                                    , payroll.CostCenter, "B" + payroll.Id.ToString(), true));
                                break;
                            case SAPMappingType.GrossIncome:
                                context.Response.Write(map.GetCSVRow(payroll.GrossIncomeValue
                                    , payroll.Employee.InternalCode, payroll.Employee.EmployeeType
                                    , payroll.CostCenter, "G" + payroll.Id.ToString(), true));
                                break;
                            case SAPMappingType.NetIncome:
                                context.Response.Write(map.GetCSVRow(payroll.NetIncomeValue
                                    , payroll.Employee.InternalCode, payroll.Employee.EmployeeType
                                    , payroll.CostCenter, "N" + payroll.Id.ToString(), true));
                                break;
                            case SAPMappingType.PaymentTotal:
                                context.Response.Write(map.GetCSVRow(payroll.PaidValue
                                    , payroll.Employee.InternalCode, payroll.Employee.EmployeeType
                                    , payroll.CostCenter, "P" + payroll.Id.ToString(), true));
                                break;
                            case SAPMappingType.Component:
                                PayrollComponent component = components.SingleOrDefault(pc => pc.EmployeeComponent.EmployeeComponentDefinition.Id == map.EmployeeComponentDefinition.Id);

                                if (component == null) 
                                    break;

                                context.Response.Write(map.GetCSVRow(
                                    component.EndMonthValue - component.StartMonthValue
                                    , payroll.Employee.InternalCode, payroll.Employee.EmployeeType
                                    , payroll.CostCenter, "C" + component.Id.ToString(), true));
                                break;
                        }
                    }
                }
                
                // transaction mappings
                IList<SAPExportMapping> tranMappings = Apollo.Application.CurrentSession
                    .QueryOver<SAPExportMapping>()
                    .Where(m => m.BelongsTo == null && m.State == State.Active && m.Type == SAPMappingType.Transaction)
                    .List();
                IEnumerable<int> sapTransactionDefIds = tranMappings.Select<SAPExportMapping, int>(m => m.TransactionDefinition.Id);
                foreach (SAPExportMapping map in tranMappings)
                {
                    map.LastDayOfMonth = lastDayOfMonth;
                    map.AccountSufixPF = ACCOUNT_PF_SUFIX;
                    map.AccountSufixPJ = ACCOUNT_PJ_SUFIX;
                }
                
                    
                // generate line foreach transaction
                foreach (Transaction tran in Apollo.Application.CurrentSession
                    .QueryOver<Transaction>()
                    .Where(t => t.AccountingMonth.Id == accountingMonthId)
                    // take only the transactions that will be exported
                    .WhereRestrictionOn(t => t.Definition.Id).IsIn(sapTransactionDefIds.ToArray()).List())
                {
                    foreach (SAPExportMapping map in tranMappings) {
                        if (tran.Definition.Id != map.TransactionDefinition.Id)
                            continue;

                        context.Response.Write(map.GetCSVRow(
                                    tran.GrossValue
                                    , tran.Employee.InternalCode, tran.Employee.EmployeeType
                                    , tran.CostCenter, "T" + tran.Id.ToString(), true));
                    }
                    
                }
                
                //// generate lines from transaction archive
                //foreach (TransactionArchive tran in Apollo.Application.CurrentSession
                //    .QueryOver<TransactionArchive>()
                //    .Where(t => t.AccountingMonth.Id == accountingMonthId)
                //    .WhereRestrictionOn(t => t.Definition.Id).IsIn(sapTransactionDefIds.ToArray()).List())
                //{
                //    foreach (SAPExportMapping map in tranMappings)
                //    {
                //        if (tran.Definition.Id != map.TransactionDefinition.Id)
                //            continue;

                //        context.Response.Write("\n" + map.GetCSVRow(
                //                    tran.GrossValue
                //                    , tran.Employee.InternalCode, tran.Employee.EmployeeType
                //                    , tran.CostCenter, "TH" + tran.Id.ToString()));
                //    }
                //}
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }
}